package com.gxc.string;

/**
 * 43. 字符串相乘
 * 给定两个以字符串形式表示的非负整数 num1 和 num2，返回 num1 和 num2 的乘积，它们的乘积也表示为字符串形式。
 *
 * 注意：不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
 *
 * 不能转换为数字，则用字符相减代替  charAt(j) - '0'
 */
public class Multiply {

    public static void main(String[] args) {
        //System.out.println(add("111", "889"));
        //System.out.println(handle("2", "3"));
        System.out.println(handle("123", "456"));
        //System.out.println(handle("20", "456"));
    }

    /**
     * 按各位相乘后相加
     * @param num1
     * @param num2
     * @return
     */
    public static String handle(String num1, String num2) {
        if ("0".equals(num1) || "0".equals(num2)) return "0";
        int n1 = num1.length() - 1, n2;
        String res = "";
        int cur1 = 0;
        int cur2 = 0;
        int sum = 0;
        int carry = 0;
        int zero = 0;
        while (n1>=0) {
            StringBuffer sb = new StringBuffer();
            zero = num1.length() - 1 - n1;
            for (int i = 0; i < zero; i++) {
                sb.append("0");
            }
            carry = 0;
            n2 = num2.length() - 1;
            cur1 = num1.charAt(n1) - '0';
            while (n2>=0) {
                cur2 = num2.charAt(n2) - '0';
                sum = cur1 * cur2 + carry;
                sb.append(sum%10);
                carry = sum /10;
                n2--;
            }
            if (carry>0) sb.append(carry);
            System.out.println(sb.reverse().toString());
            res = add(res, sb.reverse().toString());
            n1--;
        }
        return res;
    }

    private static String add(String num1, String num2) {
        int n1 = num1.length()-1, n2 = num2.length()-1;
        StringBuffer sb = new StringBuffer();
        int sum = 0;
        int carry = 0;
        while (n1 >= 0 && n2 >= 0) {
            int i = num1.charAt(n1) - '0';
            int j = num2.charAt(n2) - '0';
            sum = i + j + carry;
            sb.append(sum%10);
            carry = sum /10;
            n1--;
            n2--;
        }
        while (n1 >= 0) {
            int i = num1.charAt(n1) - '0';
            sum = i  + carry;
            sb.append(sum%10);
            carry = sum /10;
            n1--;
        }
        while (n2 >= 0) {
            int j = num2.charAt(n2) - '0';
            sum = j  + carry;
            sb.append(sum%10);
            carry = sum /10;
            n2--;
        }
        if (carry > 0) sb.append("1");
        return sb.reverse().toString();
    }

    /**
     * 做加法
     */
    class Solution {
        public String multiply(String num1, String num2) {
            if (num1.equals("0") || num2.equals("0")) {
                return "0";
            }
            String ans = "0";
            int m = num1.length(), n = num2.length();
            for (int i = n - 1; i >= 0; i--) {
                StringBuffer curr = new StringBuffer();
                int add = 0;
                for (int j = n - 1; j > i; j--) {
                    curr.append(0);
                }
                int y = num2.charAt(i) - '0';
                for (int j = m - 1; j >= 0; j--) {
                    int x = num1.charAt(j) - '0';
                    int product = x * y + add;
                    curr.append(product % 10);
                    add = product / 10;
                }
                if (add != 0) {
                    curr.append(add % 10);
                }
                ans = addStrings(ans, curr.reverse().toString());
            }
            return ans;
        }

        public String addStrings(String num1, String num2) {
            int i = num1.length() - 1, j = num2.length() - 1, add = 0;
            StringBuffer ans = new StringBuffer();
            while (i >= 0 || j >= 0 || add != 0) {
                int x = i >= 0 ? num1.charAt(i) - '0' : 0;
                int y = j >= 0 ? num2.charAt(j) - '0' : 0;
                int result = x + y + add;
                ans.append(result % 10);
                add = result / 10;
                i--;
                j--;
            }
            ans.reverse();
            return ans.toString();
        }
    }


    /**
     * 做乘法
     */
    class Solution2 {
        public String multiply(String num1, String num2) {
            if (num1.equals("0") || num2.equals("0")) {
                return "0";
            }
            int m = num1.length(), n = num2.length();
            int[] ansArr = new int[m + n];
            for (int i = m - 1; i >= 0; i--) {
                int x = num1.charAt(i) - '0';
                for (int j = n - 1; j >= 0; j--) {
                    int y = num2.charAt(j) - '0';
                    ansArr[i + j + 1] += x * y;
                }
            }
            for (int i = m + n - 1; i > 0; i--) {
                ansArr[i - 1] += ansArr[i] / 10;
                ansArr[i] %= 10;
            }
            int index = ansArr[0] == 0 ? 1 : 0;
            StringBuffer ans = new StringBuffer();
            while (index < m + n) {
                ans.append(ansArr[index]);
                index++;
            }
            return ans.toString();
        }
    }

}
